home *** CD-ROM | disk | FTP | other *** search
- /*
- * s3wgl.c
- *
- * Originally from Mesa 3Dfx driver, rewritten and bugfixed
- */
-
- #ifdef S3
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- #include <GL/gl.h>
- #include <GL/glu.h>
-
- #ifdef __cplusplus
- }
- #endif
-
- #include <stdio.h>
- #include <windows.h>
-
- #include "s3mesa.h"
-
- #define _DLLEXPORT_ __declspec(dllexport)
- #define MAX_MESA_ATTRS 20
-
- //#define DEBUG_WGL
-
- struct __extensions__
- {
- PROC proc;
- char *name;
- };
-
- struct __extensions__ ext[] = {
-
- #ifdef GL_EXT_polygon_offset
- { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" },
- #endif
- { (PROC)glBlendEquationEXT, "glBlendEquationEXT" },
- { (PROC)glBlendColorEXT, "glBlendColorExt" },
- { (PROC)glVertexPointerEXT, "glVertexPointerEXT" },
- { (PROC)glNormalPointerEXT, "glNormalPointerEXT" },
- { (PROC)glColorPointerEXT, "glColorPointerEXT" },
- { (PROC)glIndexPointerEXT, "glIndexPointerEXT" },
- { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" },
- { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" },
- { (PROC)glGetPointervEXT, "glGetPointervEXT" },
- { (PROC)glArrayElementEXT, "glArrayElementEXT" },
- { (PROC)glDrawArraysEXT, "glDrawArrayEXT" },
- { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" },
- { (PROC)glBindTextureEXT, "glBindTextureEXT" },
- { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" },
- { (PROC)glGenTexturesEXT, "glGenTexturesEXT" },
- { (PROC)glIsTextureEXT, "glIsTextureEXT" },
- { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" },
- { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" },
- { (PROC)glTexImage3DEXT, "glTexImage3DEXT" },
- { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" },
- };
- int qt_ext = sizeof(ext) / sizeof(ext[0]);
-
-
-
- /* See PIXELFORMATDESCRIPTOR in MSVC help */
-
- struct __pixelformat__
- {
- PIXELFORMATDESCRIPTOR pfd; // The standard Windows DC pixelformat
- GLint mesaAttr[MAX_MESA_ATTRS]; // The attributes that will be interpreted by the driver
- };
-
- /* Our supported pixelformats; all reported as 32-bit */
- struct __pixelformat__ pix[] =
- {
- /* Depth cases must come before non-depth cases, so in the case of the application requesting
- * a Z-buffer depth other than 16-bits one is still allocated even if it isn't as wide
- * as that requested */
-
- /* With depth buffer, without double buffer */
- { { sizeof(PIXELFORMATDESCRIPTOR), 1,
- PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_ACCELERATED|PFD_SUPPORT_GDI,
- PFD_TYPE_RGBA,
- 24, 8, 0, 8, 8, 8, 16, 8, 24,
- 8, 2, 2, 2, 2, 16, 8, 0, 0, 0, 0, 0, 0 },
- {
- S3MESA_ALPHA_SIZE, 8,
- S3MESA_DEPTH_SIZE, 16,
- S3MESA_STENCIL_SIZE, 8,
- S3MESA_ACCUM_SIZE, 8,
- S3MESA_NONE }
- },
-
- /* Without depth buffer and double buffer */
- { { sizeof(PIXELFORMATDESCRIPTOR), 1,
- PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_ACCELERATED|PFD_SUPPORT_GDI,
- PFD_TYPE_RGBA,
- 24, 8, 0, 8, 8, 8, 16, 8, 24,
- 8, 2, 2, 2, 2, 0, 8, 0, 0, 0, 0, 0, 0 },
- {
- S3MESA_ALPHA_SIZE, 8,
- S3MESA_DEPTH_SIZE, 0,
- S3MESA_STENCIL_SIZE, 8,
- S3MESA_ACCUM_SIZE, 8,
- S3MESA_NONE }
- },
-
- /* With depth buffer & double buffer */
- { { sizeof(PIXELFORMATDESCRIPTOR), 1,
- PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_ACCELERATED|PFD_DOUBLEBUFFER|PFD_SUPPORT_GDI,
- PFD_TYPE_RGBA,
- 24, 8, 0, 8, 8, 8, 16, 8, 24,
- 8, 2, 2, 2, 2, 16, 8, 0, 0, 0, 0, 0, 0 },
- {
- S3MESA_DOUBLEBUFFER,
- S3MESA_ALPHA_SIZE, 8,
- S3MESA_DEPTH_SIZE, 16,
- S3MESA_STENCIL_SIZE, 8,
- S3MESA_ACCUM_SIZE, 8,
- S3MESA_NONE }
- },
-
- /* Without depth buffer, with double buffer */
- { { sizeof(PIXELFORMATDESCRIPTOR), 1,
- PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_ACCELERATED|PFD_DOUBLEBUFFER|PFD_SUPPORT_GDI,
- PFD_TYPE_RGBA,
- 24, 8, 0, 8, 8, 8, 16, 8, 24,
- 8, 2, 2, 2, 2, 0, 8, 0, 0, 0, 0, 0, 0 },
- {
- S3MESA_DOUBLEBUFFER,
- S3MESA_ALPHA_SIZE, 8,
- S3MESA_DEPTH_SIZE, 0,
- S3MESA_STENCIL_SIZE, 8,
- S3MESA_ACCUM_SIZE, 8,
- S3MESA_NONE }
- },
-
- };
- int qt_pix = sizeof(pix) / sizeof(pix[0]); // Number of pixelformats in the driver
-
-
- static int curPFD = 0;
-
- #define MAX_CONTEXTS 32 // THIS MUST NOT BE CHANGED without redoing the MonitorProcs
-
- /* This structure contains enough information to let us manage everything */
- typedef struct {
- s3MesaContext s3ctx;
- HDC hDC;
- WNDPROC hWNDOldProc;
- HWND hWND;
- } Contextlist;
- static Contextlist ctxlist[MAX_CONTEXTS+1];
- static int context_count = 0; // Contexts allocated
- static int current_context = 0; // Handle of the current context: 0 means no context
- static s3MesaContext ctx = NULL; // Current rendering context: NULL is no context
-
-
- #if 0
-
- /*
- * This monitors all the Windows messages that comes through, and performs any tasks that
- * need to be done - particularly, resizes and moves in Windows mode.
- */
- LONG APIENTRY __wglMonitor(HWND hwnd,UINT message,UINT wParam,LONG lParam)
- {
- if (ctx && hwnd == hWND)
- {
- switch(message)
- {
- case WM_MOVE:
- s3MesaMoveWindow(ctx, lParam&0xffff, lParam>>16);
- break;
-
- case WM_DISPLAYCHANGE:
- case WM_SIZE:
- s3MesaResizeWindow(ctx, lParam&0xffff, lParam>>16);
- break;
-
- case WM_ACTIVATE:
- /* In fullscreen mode, probably need to do something here */
- break;
- }
- }
-
- return(hWNDOldProc(hwnd,message,wParam,lParam));
- }
- #endif
-
- #define MONITORPROC(a) \
- LONG APIENTRY __wglMonitor##a(HWND hwnd,UINT message,UINT wParam,LONG lParam) \
- {\
- if (ctx && (ctx == ctxlist[a].s3ctx) && (hwnd == ctxlist[a].hWND)) { \
- switch(message) { \
- case WM_MOVE: \
- s3MesaMoveWindow(ctxlist[a].s3ctx, lParam&0xffff, lParam>>16); \
- break; \
- case WM_DISPLAYCHANGE: \
- case WM_SIZE: \
- s3MesaResizeWindow(ctxlist[a].s3ctx, lParam&0xffff, lParam>>16); \
- break; \
- case WM_ACTIVATE: \
- /* In fullscreen mode, probably need to do something here */ \
- break; \
- } \
- } \
- return(ctxlist[a].hWNDOldProc(hwnd, message, wParam, lParam)); \
- }
-
- MONITORPROC( 0); MONITORPROC( 1); MONITORPROC( 2); MONITORPROC( 3); MONITORPROC( 4);
- MONITORPROC( 5); MONITORPROC( 6); MONITORPROC( 7); MONITORPROC( 8); MONITORPROC( 9);
- MONITORPROC(10); MONITORPROC(11); MONITORPROC(12); MONITORPROC(13); MONITORPROC(14);
- MONITORPROC(15); MONITORPROC(16); MONITORPROC(17); MONITORPROC(18); MONITORPROC(19);
- MONITORPROC(20); MONITORPROC(21); MONITORPROC(22); MONITORPROC(23); MONITORPROC(24);
- MONITORPROC(25); MONITORPROC(26); MONITORPROC(27); MONITORPROC(28); MONITORPROC(29);
- MONITORPROC(30); MONITORPROC(31); MONITORPROC(32);
-
- WNDPROC monitorproclist[MAX_CONTEXTS+1] = {
- __wglMonitor0, __wglMonitor1, __wglMonitor2, __wglMonitor3, __wglMonitor4,
- __wglMonitor5, __wglMonitor6, __wglMonitor7, __wglMonitor8, __wglMonitor9,
- __wglMonitor10, __wglMonitor11, __wglMonitor12, __wglMonitor13, __wglMonitor14,
- __wglMonitor15, __wglMonitor16, __wglMonitor17, __wglMonitor18, __wglMonitor19,
- __wglMonitor20, __wglMonitor21, __wglMonitor22, __wglMonitor23, __wglMonitor24,
- __wglMonitor25, __wglMonitor26, __wglMonitor27, __wglMonitor28, __wglMonitor29,
- __wglMonitor30, __wglMonitor31, __wglMonitor32
- };
-
-
-
- /*
- * CopyContext copies the state from one context to another - not currently supported
- */
- _DLLEXPORT_ BOOL APIENTRY wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)
- {
- return(FALSE);
- }
-
-
- /*
- * CreateContext - creates an OpenGL rendering context to work onto a Windows DC
- */
- _DLLEXPORT_ HGLRC APIENTRY wglCreateContext(HDC hdc)
- {
- HWND hWnd;
- WNDPROC oldProc;
- int slot;
-
- /* Fail if we have allocated all our contexts */
- if (context_count == MAX_CONTEXTS)
- {
- SetLastError(0);
- return(NULL);
- }
- /* No window; nothing to render on; abort */
- if(!(hWnd = WindowFromDC(hdc)))
- {
- SetLastError(0);
- return(NULL);
- }
- /* A valid pixelformat must have been set into the DC and therefore our driver */
- if(curPFD == 0)
- {
- SetLastError(0);
- return(NULL);
- }
- /* Set up the log */
- fclose(stderr);
- fopen("MESA.LOG","w");
-
- /* Find an empty slot */
- for (slot=1; slot<MAX_CONTEXTS+1; slot++) {
- if (!ctxlist[slot].s3ctx)
- break;
- }
- if (slot == (MAX_CONTEXTS+1)) {
- SetLastError(0);
- return(NULL);
- }
-
- /* Set up our monitoring of the window procedure, to catch any critical Windows messages */
- if ((oldProc = (WNDPROC) GetWindowLong(hWnd, GWL_WNDPROC)) != monitorproclist[slot])
- {
- ctxlist[slot].hWNDOldProc = oldProc;
- SetWindowLong(hWnd, GWL_WNDPROC, (LONG)monitorproclist[slot]);
- }
-
- /* Create the S3Mesa context */
- if(!(ctxlist[slot].s3ctx = s3MesaCreateBestContext((GLuint)hWnd, 0, 0, pix[curPFD - 1].mesaAttr)))
- {
- SetLastError(0);
- return(NULL);
- }
- context_count++;
-
- /* Save our critical internals */
- ctxlist[slot].hDC = hdc;
- ctxlist[slot].hWND = hWnd;
-
- /* And... we're off! */
- return((HGLRC) slot);
- }
-
- /*
- * Layers not supported
- */
- _DLLEXPORT_ HGLRC APIENTRY wglCreateLayerContext(HDC hdc,int iLayerPlane)
- {
- SetLastError(0);
- return(NULL);
- }
-
- /*
- * DeleteContext - kill the current context and shut down OpenGL
- */
- _DLLEXPORT_ BOOL APIENTRY wglDeleteContext(HGLRC hglrc)
- {
- if (((int) hglrc < (MAX_CONTEXTS+1)) && ctxlist[(int) hglrc].s3ctx)
- {
- s3MesaDestroyContext(ctxlist[(int) hglrc].s3ctx);
- ctxlist[(int) hglrc].s3ctx = 0;
- context_count--;
- return(TRUE);
-
- if ((int) hglrc == current_context) {
- current_context = 0;
- ctx = 0;
- }
- }
- SetLastError(0);
- return(FALSE);
- }
-
- /*
- * GetCurrentContext - return it
- */
- _DLLEXPORT_ HGLRC APIENTRY wglGetCurrentContext(VOID)
- {
- if (current_context)
- return((HGLRC) current_context);
-
- SetLastError(0);
- return(NULL);
- }
-
- /*
- * GetCurrentDC - return the DC associated with the rendering context
- */
- _DLLEXPORT_ HDC APIENTRY wglGetCurrentDC(VOID)
- {
- if (ctx)
- return(ctxlist[current_context].hDC);
-
- SetLastError(0);
- return(NULL);
- }
-
- /*
- * GetProcAddress - return the address of an appropriate extension
- */
- _DLLEXPORT_ PROC APIENTRY wglGetProcAddress(LPCSTR lpszProc)
- {
- int i;
-
- #ifdef DEBUG_WGL
- fprintf(stderr, "Attempt to reference extension %s\n", lpszProc);
- #endif
-
- for(i = 0;i < qt_ext;i++)
- if(!strcmp(lpszProc,ext[i].name))
- return(ext[i].proc);
-
- SetLastError(0);
- return(NULL);
- }
-
- /*
- * MakeCurrent - make a particular context the 'current' one
- */
- _DLLEXPORT_ BOOL APIENTRY wglMakeCurrent(HDC hdc, HGLRC hglrc)
- {
- if (hglrc == 0) {
- ctx = NULL;
- s3MesaMakeCurrent(ctx);
- return(TRUE);
- }
-
- if (((int) hglrc >= (MAX_CONTEXTS+1)) ||
- (ctxlist[(int) hglrc].s3ctx == NULL) ||
- WindowFromDC(hdc) != ctxlist[(int) hglrc].hWND)
- {
- SetLastError(0);
- return(FALSE);
- }
-
- ctxlist[current_context].hDC = hdc;
- ctx = ctxlist[(int) hglrc].s3ctx;
- s3MesaMakeCurrent(ctx);
-
- return(TRUE);
- }
-
- /*
- * ShareLists - not supported, but return something appropriate in idiot cases
- */
- _DLLEXPORT_ BOOL APIENTRY wglShareLists(HGLRC hglrc1,HGLRC hglrc2)
- {
- if (hglrc1 != hglrc2)
- {
- SetLastError(0);
- return(FALSE);
- }
- return(TRUE);
- }
-
-
- /*
- * Font functions: not supported
- */
- _DLLEXPORT_ BOOL APIENTRY wglUseFontBitmapsA(HDC hdc,DWORD first,DWORD count,DWORD listBase)
- {
- return(FALSE);
- }
-
- _DLLEXPORT_ BOOL APIENTRY wglUseFontBitmapsW(HDC hdc,DWORD first,DWORD count,DWORD listBase)
- {
- return(wglUseFontBitmapsA(hdc, first, count, listBase));
- }
-
- _DLLEXPORT_ BOOL APIENTRY wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,
- DWORD listBase,FLOAT deviation,
- FLOAT extrusion,int format,
- LPGLYPHMETRICSFLOAT lpgmf)
- {
- SetLastError(0);
- return(FALSE);
- }
-
- _DLLEXPORT_ BOOL APIENTRY wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,
- DWORD listBase,FLOAT deviation,
- FLOAT extrusion,int format,
- LPGLYPHMETRICSFLOAT lpgmf)
- {
- SetLastError(0);
- return(FALSE);
- }
-
-
- /*
- * Layers not supported
- */
- _DLLEXPORT_ BOOL APIENTRY wglDescribeLayerPlane(HDC hdc,int iPixelFormat,
- int iLayerPlane,UINT nBytes,
- LPLAYERPLANEDESCRIPTOR plpd)
- {
- SetLastError(0);
- return(FALSE);
- }
-
- _DLLEXPORT_ int APIENTRY wglSetLayerPaletteEntries(HDC hdc,int iLayerPlane,
- int iStart,int cEntries,
- CONST COLORREF *pcr)
- {
-
- fprintf(stderr, "SetLayerPaletteEntries\n");
-
- SetLastError(0);
- return(0);
- }
-
- _DLLEXPORT_ int APIENTRY wglGetLayerPaletteEntries(HDC hdc,int iLayerPlane,
- int iStart,int cEntries,
- COLORREF *pcr)
- {
- fprintf(stderr, "GetLayerPaletteEntries\n");
-
- SetLastError(0);
- return(0);
- }
-
- _DLLEXPORT_ BOOL APIENTRY wglRealizeLayerPalette(HDC hdc,int iLayerPlane,BOOL bRealize)
- {
- fprintf(stderr, "RealizeLayerPaletteEntries\n");
-
- SetLastError(0);
- return(FALSE);
- }
-
- _DLLEXPORT_ BOOL APIENTRY wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)
- {
- if (ctx &&
- (WindowFromDC(hdc) == ctxlist[current_context].hWND) &&
- (fuPlanes == WGL_SWAP_MAIN_PLANE))
- {
- s3MesaSwapBuffers();
- return(TRUE);
- }
- SetLastError(0);
- return(FALSE);
- }
-
-
- /* Pixel Format functions */
-
- /*
- * ChoosePixelFormat - compare our supported device pixelformats against the one
- * supplied and match as best we can
- */
- _DLLEXPORT_ int APIENTRY wglChoosePixelFormat(HDC hdc,
- CONST PIXELFORMATDESCRIPTOR *ppfd)
- {
- int i,best = -1,bestdelta = 0x7FFFFFFF,delta;
-
- if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1)
- {
- SetLastError(0);
- return(0);
- }
-
- for(i = 0;i < qt_pix;i++)
- {
- delta = 0; // 'difference' counter
-
- /* Any of these failing is a critical fail */
- if((ppfd->dwFlags & PFD_DRAW_TO_WINDOW) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
- continue;
- if((ppfd->dwFlags & PFD_DRAW_TO_BITMAP) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
- continue;
- if((ppfd->dwFlags & PFD_SUPPORT_GDI) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI))
- continue;
- if((ppfd->dwFlags & PFD_SUPPORT_OPENGL) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
- continue;
- if(!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
- ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
- continue;
- if(!(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
- ((ppfd->dwFlags & PFD_STEREO) != (pix[i].pfd.dwFlags & PFD_STEREO)))
- continue;
-
- /* These are non-critical fails - match as best we can */
- if(ppfd->iPixelType != pix[i].pfd.iPixelType)
- delta++;
- if (ppfd->cDepthBits != pix[i].pfd.cDepthBits)
- delta++;
-
- /* Is this the best? */
- if(delta < bestdelta)
- {
- best = i + 1;
- bestdelta = delta;
- if(bestdelta == 0)
- break;
- }
- }
-
- /* not found.... whoops! */
- if(best == -1)
- {
- SetLastError(0);
- return(0);
- }
- return(best);
- }
-
- /*
- * DescribePixelFormat
- */
- _DLLEXPORT_ int APIENTRY wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
- LPPIXELFORMATDESCRIPTOR ppfd)
- {
- if(iPixelFormat < 1 || iPixelFormat > qt_pix || nBytes != sizeof(PIXELFORMATDESCRIPTOR))
- {
- SetLastError(0);
- return(0);
- }
- *ppfd = pix[iPixelFormat - 1].pfd;
- return(qt_pix);
- }
-
- /* UNKNOWN !!!
- wglGetDefaultProcAddress()
- */
-
- /*
- * GetPixelFormat
- */
- _DLLEXPORT_ int APIENTRY wglGetPixelFormat(HDC hdc)
- {
- if(curPFD == 0)
- {
- SetLastError(0);
- return(0);
- }
- return(curPFD);
- }
-
- /*
- * SetPixelFormat
- */
- _DLLEXPORT_ BOOL APIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
- PIXELFORMATDESCRIPTOR *ppfd)
- {
- if(iPixelFormat < 1 || iPixelFormat > qt_pix || ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR))
- {
- SetLastError(0);
- return(FALSE);
- }
- curPFD = iPixelFormat;
- return(TRUE);
- }
-
-
-
- /*
- * Double Buffer call
- */
- _DLLEXPORT_ BOOL APIENTRY wglSwapBuffers(HDC hdc)
- {
- if(!ctx)
- {
- SetLastError(0);
- return(FALSE);
- }
- s3MesaSwapBuffers();
- return(TRUE);
- }
-
- #endif /* S3 */
-
-